package com.yonyou.pmclouds.basecom.datasource;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import org.springframework.jdbc.datasource.AbstractDataSource;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.yonyou.pmclouds.basecom.multilanguage.ResUtil;

import lombok.Getter;
import lombok.Setter;

//public class DynamicDataSource extends AbstractRoutingDataSource {
public class DynamicDataSource extends AbstractDataSource {

	String datasourcekey="";
	private static Map<Object,DataSource> dataSourceMap=new HashMap<Object, DataSource>();
	@Setter
	@Getter
	private DruidDataSource mainDataSource;
	
	protected ScheduledExecutorService destroyScheduler ;
	private volatile ScheduledFuture<?> destroySchedulerFuture;
	private DestroyTask destroyTask;
	
	public DynamicDataSource()
	{
		super();
		init();
	}
	
	public void init()
	{
		destroyScheduler = Executors.newScheduledThreadPool(1);
		destroyTask = new DestroyTask();
		destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destroyTask, 0, 3600000,TimeUnit.MILLISECONDS);
	}
	@Override
	public Connection getConnection() throws SQLException {
		initDatasource();
		return dataSourceMap.get(datasourcekey).getConnection();
	}

	@Override
	public Connection getConnection(String username, String password) throws SQLException {
		initDatasource();
		return dataSourceMap.get(datasourcekey).getConnection(username, password);
	}
	
	private void initDatasource()
	{
		if(dataSourceMap.get(datasourcekey)==null)
		{
			Properties properties = new Properties();
			DataSourceVO ds = this.getTargetDataSource();
			properties.setProperty("url",ds.getUrl());
			properties.setProperty("username",ds.getUsername());
			properties.setProperty("password",ds.getPassword());
			properties.setProperty("initialsize",String.valueOf(mainDataSource.getInitialSize()));
			properties.setProperty("maxactive",String.valueOf(mainDataSource.getMaxActive()));
			properties.setProperty("minidle",String.valueOf(mainDataSource.getMinIdle()));
			properties.setProperty("maxwait",String.valueOf(mainDataSource.getMaxWait()));
			properties.setProperty("validationquery",String.valueOf(mainDataSource.getValidationQuery()));
			properties.setProperty("testonborrow",String.valueOf(mainDataSource.isTestOnBorrow()));
			properties.setProperty("testonreturn",String.valueOf(mainDataSource.isTestOnReturn()));
			properties.setProperty("testwhileidle",String.valueOf(mainDataSource.isTestWhileIdle()));
			properties.setProperty("timebetweenevictionrunsmillis",String.valueOf(mainDataSource.getTimeBetweenEvictionRunsMillis()));
			properties.setProperty("minevictableidletimemillis",String.valueOf(mainDataSource.getMinEvictableIdleTimeMillis()));
			properties.setProperty("removeabandoned",String.valueOf(mainDataSource.isRemoveAbandoned()));
			properties.setProperty("removeabandonedtimeout",String.valueOf(mainDataSource.getRemoveAbandonedTimeout()));
			properties.setProperty("logabandoned",String.valueOf(mainDataSource.isLogAbandoned()));
			properties.setProperty("proxyfilters",String.valueOf(mainDataSource.getProxyFilters()));//filters
			
			try {
				DataSource datasource = DruidDataSourceFactory.createDataSource(properties);
				dataSourceMap.put(datasourcekey, datasource);
			} catch (Exception e) {
				throw new RuntimeException(ResUtil.getInstance().getResString("username"));
			}
			
		}
	}
	
	private DataSourceVO getTargetDataSource()
	{
		DataSourceVO datasource= new DataSourceVO();
		datasource.setUrl("jdbc\\:mysql\\://172.16.72.100\\:3306/clouds");
		datasource.setUsername("root");
		datasource.setPassword("root");
		return datasource;
	}
	
	public class DestroyTask implements Runnable {

        @Override
        public void run() {
        	destroy();
        }

    }
	private void destroy()
	{
		for(Object obj : dataSourceMap.keySet())
		{
			DruidDataSource ds = (DruidDataSource)dataSourceMap.get(obj);
			if(ds.getActiveCount()==0)
			{
				ds.close();
				dataSourceMap.remove(obj);
			}
		}
	}

}
